package jp.co.apl.haven_enquete.android.activity;

import java.util.ArrayList;
import java.util.List;

import jp.co.apl.haven.generated.HavenProtos.Answer;
import jp.co.apl.haven.generated.HavenProtos.InputType;
import jp.co.apl.haven.generated.HavenProtos.Question;
import jp.co.apl.haven.generated.HavenProtos.SelectionItem;
import jp.co.apl.haven_enquete.android.R;
import jp.co.apl.haven_enquete.android.dao.AnswerDataDao;
import jp.co.apl.haven_enquete.android.dao.QuestionDataDao;
import jp.dev7.android.util.Activities;
import jp.dev7.android.util.Layouts;
import jp.dev7.android.util.Toasts;
import jp.dev7.android.util.Views;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.net.Uri;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.protobuf.InvalidProtocolBufferException;

/**
 * 
 * @author narazaki.daishi
 */
public class Main extends Activity {

    private static final int REQUEST_CODE = 0;

    private ActivityCommon activityCommon = new ActivityCommon(this);

    private QuestionDataDao qDao;

    private AnswerDataDao aDao;

    /** 表示する質問. */
    private Question question;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        qDao = new QuestionDataDao(this);
        aDao = new AnswerDataDao(this);

        // TODO あとで消す
        qDao.initDataFile();

        // 表示する質問を取得
        question = getQuestion();
        if (question == null) {
            finish();
            return;
        }

        // 前回の回答を取得
        Answer answer = aDao.loadAsMap().get(question.getId());
        if (answer != null) {
            Log.d("haven", "answer = " + answer.getAnswer());
        }

        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.main);
        activityCommon.setActionBar("質問");
        Activities.setClickListnerToButton(
            this,
            R.id.actionBar_prevButton,
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onClickPrevButton();
                }
            });
        Activities.setClickListnerToButton(
            this,
            R.id.actionBar_nextButton,
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startNextActivity(qDao.getNextQuestionId(question.getId()));
                }
            });

        // 質問タイトル
        Activities.setText(this, R.id.main_title, question.getTitle());
        // 質問本文
        Activities.setText(this, R.id.main_text, question.getText());

        // 入力欄作成
        LinearLayout inner =
            Activities.findViewById(this, R.id.main_includeArea);
        {
            if (question.getInputType() == InputType.SELECT) {
                // 選択式
                setUpSelection(inner, answer);
            } else if (question.getInputType() == InputType.NUMBER) {
                // 数値入力式
                setUpNumberInput(inner, answer);
            } else {
                Log.e("haven", "invalid question data.");
                finish();
                return;
            }
        }

        final GestureLibrary gl =
            GestureLibraries.fromRawResource(this, R.raw.gestures);
        GestureOverlayView gov =
            (GestureOverlayView) findViewById(R.id.main_gesture);
        gov.addOnGesturePerformedListener(new OnGesturePerformedListener() {
            @Override
            public void onGesturePerformed(GestureOverlayView overlay,
                    Gesture gesture) {
                Toasts.show(Main.this, "g = " + gesture);
                ArrayList<Prediction> gs = gl.recognize(gesture);
                for (Prediction prediction : gs) {
                    Toasts.show(Main.this, "g = " + prediction.name);
                }
            }
        });
    }

    private Question getQuestion() {
        {
            Uri uri = getIntent().getData();
            if (uri == null) {
                uri = Uri.parse("content://jp.co.apl.haven_enquete/question");
            }
            Cursor cur = Activities.getFromProvider(this, uri);
            if (!cur.moveToFirst() || cur.getBlob(0) == null) {
                Log.e("haven", "no question data.");
                return null;
            }
            try {

                Question result = Question.parseFrom(cur.getBlob(0));
                Log.d("haven", "question id = " + result.getId());
                return result;

            } catch (InvalidProtocolBufferException e) {
                Log.e("haven", "invalid question data.", e);
                return null;
            }
        }
    }

    @Override
    protected void onDestroy() {
        activityCommon = null;
        qDao = null;
        aDao = null;
        question = null;
        super.onDestroy();
    }

    /**
     * 選択肢ボタンを作成.
     * 
     * @param area
     *            -
     * @param answer
     *            -
     */
    private void setUpSelection(LinearLayout area, Answer answer) {
        final List<Button> buttons = Lists.newArrayList();
        for (final SelectionItem sel : question.getSelectionItemList()) {
            Button btn = Layouts.inflate(this, R.layout.select_button);
            buttons.add(btn);

            btn.setText(sel.getLabel());

            if (answer != null && sel.getValue().equals(answer.getAnswer())) {
                btn.setBackgroundResource(R.drawable.button_selected);
            }

            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    inputAnswer(sel.getValue());
                    if (sel.getChildQuestionCount() == 0) {
                        startNextActivity(qDao.getNextQuestionId(question
                            .getId()));
                    } else {
                        startNextActivity(sel.getChildQuestion(0).getId());
                    }

                    // 選択色に変更。他のボタンは通常色へ
                    for (Button b : buttons) {
                        if (b == v) {
                            b.setBackgroundResource(R.drawable.button_selected);
                        } else {
                            b.setBackgroundResource(R.drawable.button_stateful);
                        }
                    }
                }
            });

            LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(Layouts.getParamFillWrap());
            params.setMargins(10, 0, 10, 5);
            params.weight = 1;
            area.addView(btn, params);
        }

    }

    /**
     * 数値入力フィールドを作成.
     * 
     * @param area
     *            -
     * @param answer
     *            -
     */
    private void setUpNumberInput(LinearLayout area, Answer answer) {

        LinearLayout inputNumber = Layouts.inflate(this, R.layout.input_number);
        TextView unit = Views.findViewById(inputNumber, R.id.inputNumber_unit);

        final EditText textField =
            (EditText) inputNumber.findViewById(R.id.inputNumber_textField);
        if (answer != null) {
            textField.setText(answer.getAnswer());
        }

        unit.setText(question.getUnit());

        Views.setClickListnerToButton(
            inputNumber,
            R.id.inputNumber_completeButton,
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    inputAnswer(textField.getText().toString());
                    startNextActivity(qDao.getNextQuestionId(question.getId()));
                }
            });

        // 音声入力ボタン
        Views.setClickListnerToButton(
            inputNumber,
            R.id.inputNumber_speakButton,
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {

                        Intent intent =
                            new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                        intent.putExtra(
                            RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "声で入力");
                        startActivityForResult(intent, REQUEST_CODE);

                    } catch (ActivityNotFoundException e) {
                        Toasts.show(Main.this, e.getMessage());
                    }
                }
            });

        area.addView(inputNumber, Layouts.getParamFillWrap());
    }

    private void onClickPrevButton() {

        // ウィンドウスライド方向=左から右
        getWindow().setWindowAnimations(R.style.Animation_Activity_ToRight);

        startNextActivity(qDao.getPrevQuestionId(question.getId()));
    }

    private void inputAnswer(String value) {
        if (!Strings.isNullOrEmpty(value)) {
            // 回答をDBに保存
            aDao.save(question.getId(), value);
        }
    }

    /**
     * 回答入力時処理.
     * 
     * @param value
     *            回答
     * @param nextId
     *            次の質問のID. nextId=-1の場合は回答送信画面へ遷移.
     */
    public void startNextActivity(int nextId) {

        Intent intent;
        if (nextId > 0) {
            intent = new Intent(this, Main.class);
            Uri uri = Uri.parse("content://jp.co.apl.haven_enquete/question");
            uri = ContentUris.withAppendedId(uri, nextId);
            intent.setData(uri);
            finish();
        } else {
            intent = new Intent(this, Upload.class);
        }

        startActivity(intent);

    }

    /**
     * 音声入力の結果を受け取る.
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            ArrayList<String> results =
                data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            StringBuffer sb = new StringBuffer();
            for (String result : results) {
                sb.append(result);
            }

            Toasts.show(this, sb);
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        return activityCommon.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        return activityCommon.onOptionsItemSelected(item);
    }
}
